home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * OBJMXUD.C - Turn a normal object into an XUSERDEF object.
- *
- * Whenever a library routine wants to supply a custom drawing routine
- * for a standard GEM object, it calls this to fill in an XUSERDEF
- * and attach it to the original object. The difference between an
- * XUSERDEF object and a regular USERDEF object is the contents of the
- * USERBLK structure attached to the object. A regular USERBLK contains
- * a pointer to the drawing routine followed by a longword of anything
- * the application wants. For an XUSERBLK, the ap-specific longword is
- * a pointer to the XUSERBLK itself, and then there are more fields,
- * which contain the original ob_type and the original _Ob_spec, the
- * parent tree and object to which the XUSERBLK is attached, and any
- * other data you might want to add following the predefined fields.
- * (When adding other fields after the predefined ones, pass a non-zero
- * xub_size parm to indicate how much extra data is there.)
- *
- * All this smoke-and-mirrors lets us transform a standard GEM object
- * into a new custom type without losing the information from the
- * original object. Other library routines (rsc_gstrings, for example)
- * know how to cope with XUSERBLK objects.
- *
- * Note that we properly cope with INDIRECT objects (as always), and
- * we preserve any extended type info in the original object; we only
- * change the low-order byte when plugging in the G_USERDEF ob_type.
- *************************************************************************/
-
- #include "gemfintl.h"
-
- void xob_transform(ptree, obj, pblk, pdraw, ptouch, xub_size)
- OBJECT *ptree;
- short obj;
- XUSERBLK *pblk;
- XUB_DRAWFUNC *pdraw;
- XUB_TOUCHFUNC *ptouch;
- long xub_size;
- {
- _Ob_spec_t *pspec;
- OBJECT *pobj;
-
- pobj = &ptree[obj];
- pspec = OBPSPEC(pobj);
-
- pblk->ub_draw = pdraw;
- pblk->ub_touch = ptouch;
- pblk->ub_self = pblk;
- pblk->ub_size = (xub_size == 0) ? sizeof(XUSERBLK) : xub_size;
- pblk->parent_tree = ptree;
- pblk->parent_obj = obj;
-
- pblk->ob_type = OBGTYPE(pobj);
- pobj->ob_type = OBXTYPE(pobj) | G_USERDEF;
-
- pblk->ob_spec = *pspec;
- *pspec = (_Ob_spec_t)pblk;
-
- if (ptouch != NULL) {
- pobj->ob_flags |= TOUCHEXIT;
- }
-
- }
-
-
- /*----------------------------------------------------------------------------
- * This is properly called via the macro XUBPTR(); for internal use only.
- *--------------------------------------------------------------------------*/
-
- void * _GetXub(pobj)
- OBJECT *pobj;
- {
- XUSERBLK *xub;
-
- xub = (XUSERBLK *)OBVSPEC(pobj);
- if (OBGTYPE(pobj) == G_USERDEF && xub->ub_self == xub) {
- return xub;
- }
-
- return NULL;
- }
-